home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol05 / 05 / parallel / par_poll.asm < prev    next >
Assembly Source File  |  1990-09-01  |  9KB  |  329 lines

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;;  PAR_POLL.ASM      -     Parallel Printer Port By Polling
  3. ;;;
  4. ;;;
  5. ;;;  Copyright 1990 by Ross M. Greenberg
  6. ;;;        for Microsoft Systems Journal
  7. ;;;
  8. ;;;  This program demonstrates the ability to communicate between
  9. ;;;  two PCs connected via the parallel printer port.  In order for
  10. ;;;  this program to work, a cable must be constructed that has the
  11. ;;;  following pinouts:
  12. ;;;
  13. ;;;     1 ----------  1- Common Ground
  14. ;;;     2 ---------- 15  \
  15. ;;;     3 ---------- 13   \
  16. ;;;     4 ---------- 12    > Data Out
  17. ;;;     5 ---------- 10   /
  18. ;;;     6 ---------- 11  /
  19. ;;;    10 ----------  5  \
  20. ;;;    11 ----------  6   \
  21. ;;;    12 ----------  4    > Data In
  22. ;;;    13 ----------  3   /
  23. ;;;    15 ----------  2  /
  24. ;;;
  25. ;;;  Run a copy of this program at each end of the cable.
  26. ;;;
  27. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  28.  
  29. ;;;  Public Entry Points
  30.  
  31. public     _psend, _prec, _pinit
  32.  
  33. DOSSEG
  34. .MODEL     small
  35.  
  36. .STACK     100h
  37.  
  38.  
  39. FALSE      equ   00h
  40. TRUE       equ   01h
  41.  
  42. FPTR       equ   4
  43. TIMEOUT    equ   -1
  44.  
  45. .DATA
  46. ;;no data
  47.  
  48.  
  49. .CODE
  50.  
  51. real_port  dw    0           ; the actual port used
  52. timer      dw    0           ; setup for timeout/dummy loop
  53.  
  54. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  55. ;;;
  56. ;;;  PINIT(PORT) -     Initialize the port
  57. ;;;
  58. ;;;  Port is zero based (first LPT is zero).  First, find the actual
  59. ;;;  base port to use and stuff it away in "real_port".  Then, since
  60. ;;;  we need an accurate representation of the speed of the machine,
  61. ;;;  use the tick timer in INT 0x1a to see how fast the machine is
  62. ;;;  for looping constants.  Store that away in timer, and return the
  63. ;;;  timing constant.
  64. ;;;
  65. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  66.  
  67. _pinit     proc  near
  68.      push  bp
  69.      mov   bp, sp
  70.  
  71.      push  bx
  72.      push  cx
  73.      push  dx
  74.      push  si
  75.  
  76.  
  77.      push  ds
  78.      mov   ax, 40h             ; printer ports are stored @ 40:8
  79.      mov   ds, ax
  80.      mov   bx, [bp + FPTR]
  81.      shl   bx, 1
  82.      mov   dx, word ptr 8[bx]  ; get the base port, offset by port #
  83.      pop   ds
  84.      mov   cs:[real_port], dx  ; store it
  85.  
  86.      mov   ah, 0             ; get the tick
  87.      int   01ah
  88.      mov   si, dx
  89.  
  90. @@:  mov   ah, 0
  91.      int   01ah
  92.      cmp   dx, si            ; stay in loop until tick changes
  93.      jz    @B
  94.  
  95.      mov   si, dx
  96.      xor   bx, bx
  97.  
  98.      cli                     ; accuracy means no ints!
  99. @@:  inc   bx                ; loop three times
  100.      mov   cx, bx
  101.      loop  $                 ; one
  102.      mov   cx, bx
  103.      loop  $                 ; two
  104.      mov   cx, bx
  105.      loop  $                 ; three
  106.      mov   ah, 0
  107.      int   01ah              ; get the time
  108.      cmp   dx, si            ; changed?
  109.      jz    @B                ; nope. Increase the count
  110.      sti                     ; restart interrupts
  111.      mov   cl, 9
  112.      shl   bx, cl            ; just make it a number of some sort
  113. @@:  mov   cs:[timer], bx    ; and save it
  114.      mov   ax, bx            ; and return with it in ax
  115.      pop   si
  116.      pop   dx
  117.      pop   cx
  118.      pop   bx
  119.      pop   bp
  120.      ret
  121.  
  122. _pinit     endp
  123.  
  124.  
  125. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  126. ;;;  PSEND(STRING_PTR, LEN)
  127. ;;;
  128. ;;;  Calls the send_char routine with character to send in al for LEN
  129. ;;;
  130. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  131.  
  132. _psend     proc  near
  133.      push  bp
  134.      mov   bp, sp
  135.      push  bx
  136.      push  cx
  137.      push  dx
  138.  
  139.      mov   dx, cs:[real_port]      ; base port
  140.      mov   bx, [bp + FPTR]         ; send buffer
  141.      mov   cx, [bp + FPTR + 2]     ; count
  142.      xor   bp, bp                  ; zero out counter
  143.  
  144.      jcxz  _psend_ret        ; if empty, go home
  145.  
  146. _psend_lp:
  147.      mov   al, [bx]          ; get the character
  148.      call  send_char         ; and send it
  149.      jnc   _psend_ret        ; if it didn't send, go home
  150.  
  151.      inc   bx                ; increment the pointer
  152.      inc   bp                ; and the counter
  153.      loop  _psend_lp         ; do it again
  154.  
  155. _psend_ret:
  156.      pop   dx
  157.      pop   cx
  158.      pop   bx
  159.      mov   ax, bp            ; move counter into ax
  160.      pop   bp
  161.      ret                     ; go home
  162. _psend     endp
  163.  
  164. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  165. ;;;  PREC(STRING_PTR, LEN)
  166. ;;;
  167. ;;;  Fetch LEN characters and stuff them into STRING_PTR.
  168. ;;;
  169. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  170. _prec      proc  near
  171.      push  bp
  172.      mov   bp, sp
  173.      push  bx
  174.      push  cx
  175.      push  dx
  176.  
  177.      mov   bx, [bp + FPTR]         ; receive buffer
  178.      mov   cx, [bp + FPTR + 2]     ; count
  179.      mov   dx, cs:[real_port]      ; the base port
  180.  
  181.      xor   bp, bp                  ; zero cnt
  182.  
  183.      jcxz  _prec_ret         ; no count, no probs
  184.  
  185. _prec_lp:
  186.  
  187.      call  get_char          ; get a character
  188.      jnc   bad_rec           ; whoops! set for short cnt
  189.  
  190.      mov   [bx], al          ; save the character
  191.  
  192.      inc   bx                ; bump the pointer
  193.      inc   bp                ; and the counter
  194.  
  195.      loop  _prec_lp          ; as often as you have to
  196.      jmp   _prec_ret
  197.  
  198. bad_rec:
  199.      or    bp, 08000h        ; set the short cnt indicator
  200.  
  201. _prec_ret:
  202.      pop   dx
  203.      pop   cx
  204.      pop   bx
  205.      mov   ax, bp            ; move the count in
  206.      pop   bp
  207.      ret
  208. _prec      endp
  209.  
  210.  
  211. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  212. ;;;  send-char   -     sends character in al
  213. ;;;
  214. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  215. send_char  proc  near
  216.      push  cx
  217.      mov   cx, cs:[timer]    ; get the timing constant
  218.  
  219.      mov   ah, al            ; save the character
  220.      inc   dx                ; bump up to the control port
  221.      in    al, dx            ; read it
  222.      shl   al, 1             ; pop it left
  223.      jc    go_home           ; hi bit set? Remember it's backwards
  224.  
  225.      dec   dx                ; back to the base port
  226.      mov   al, ah            ; get the character back
  227.  
  228.      shr   al,1
  229.      shr   al,1
  230.      shr   al,1
  231.      shr   al,1
  232.      and   al,0Fh            ; hi nybble first, anded just for that
  233.  
  234.      out   dx, al            ; output the nybble
  235.  
  236.      inc   dx                ; back up to control port
  237.  
  238. @@:  in    al, dx            ; get data
  239.      shl   al, 1             ; hi bit set to go?
  240.      jc    @F                ; yes
  241.      loop  @B                ; no, loop until timeout
  242.  
  243.      jmp   go_home           ; timed out. Bomb out.
  244.  
  245. @@:  dec   dx                ; back to data port
  246.      mov   al, ah            ; get the character back
  247.      or    al, 10h           ; set the hi bit (its backwards!)
  248.      out   dx, al            ; output the character
  249.  
  250.      inc   dx                ; and back to control
  251.  
  252.      mov   cx, cs:[timer]    ; get the timing constant
  253.  
  254. @@:  in    al, dx            ; and wait for ACK
  255.      shl   al, 1
  256.      jnc   go_home           ; done
  257.      loop  @B                ; looks like an error?
  258.  
  259. go_home:
  260.      dec   dx                ; mark it as ready and willing
  261.      mov   al, 10h
  262.      out   dx, al
  263.      xor   ah, ah
  264.      stc
  265.      pop   cx
  266.      ret
  267.  
  268. send_char  endp
  269.  
  270.  
  271. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  272. ;;;  get-char    -     retrieves character into al
  273. ;;;
  274. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  275.  
  276. get_char   proc  near
  277.  
  278.      push  cx
  279.      mov   cx, cs:[timer]    ; get looping constant
  280.  
  281.      inc   dx                ; upto control port
  282.  
  283. @@:  in    al, dx            ; we shall do no port before its time
  284.      shl   al, 1             ; remember its reversed
  285.      mov   ah, al            ; save it unshifted
  286.      jc    @F                ; so carry means go ahead
  287.      loop  @B                ; still set, try again
  288.  
  289.      clc                     ; carry clear means no good
  290.      pop   cx
  291.      ret                     ; go home
  292.  
  293. @@:  and   ah,0F0h           ; only the high nybble
  294.      dec   dx                ; back to data port
  295.      mov   al, 0             ; ACK the nybble
  296.      out   dx, al
  297.      inc   dx                ; back to control
  298.  
  299.      mov   cx, cs:[timer]    ; get looping constant
  300.  
  301. @@:  in    al, dx            ; wait for it
  302.      shl   al, 1
  303.      jnc   @F
  304.      loop  @B
  305.  
  306.      dec   dx                ; no go. Clean up a tad.
  307.      mov   al, 10h           ; set the flag
  308.      out   dx, al            ; output it on the data port
  309.      clc
  310.      pop   cx
  311.      ret
  312.  
  313. @@:  in    al, dx            ; get the next nybble
  314.      shr   al, 1             ; normalize it
  315.      shr   al, 1
  316.      shr   al, 1
  317.      and   al, 0Fh           ; strip off the naughty bits
  318.      or    ah, al            ; create a character in ah
  319.      dec   dx                ; ack the byte
  320.      mov   al, 10h           ; set the flag
  321.      out   dx, al            ; output it
  322.      mov   al, ah            ; retreive the character
  323.      stc
  324.      pop   cx
  325.      ret
  326. get_char   endp
  327.  
  328.      end
  329.